/*
 * Copyright (c) 2020-2021  AlgoIdeas
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021/11/27     AlgoIdeas    The first version, based on GPX Library -- GPX.cpp
 */

/*
 * GPX Library -- GPX.cpp
 * Created by: Ryan M Sutton
 *
 * Copyright (c) 2010, Ryan M Sutton
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Ryan M Sutton nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL Ryan M Sutton BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <rtthread.h>
#include <stdio.h>
#include <string.h>

#include "gpx.h"

#define _GPX_HEAD               "<gpx version=\"1.1\" creator=\"GPX C Library\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xmlns=\"http://www.topografix.com/GPX/1/1\"\n xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\"\n>\n"
#define _GPX_TAIL               "</gpx>\n"
#define _GPX_META_HEAD          "<metadata>"
#define _GPX_META_TAIL          "</metadata>\n"
#define _GPX_TRAK_HEAD          "<trk>"
#define _GPX_TRAK_TAIL          "</trk>\n"
#define _GPX_TRKSEG_HEAD        "<trkseg>"
#define _GPX_TRKSEG_TAIL        "</trkseg>\n"
#define _GPX_PT_HEAD            "<%s lat=\""
#define _GPX_PT_TAIL            "</%s>\n"

// Property Tags
#define _GPX_NAME_HEAD          "<name>"
#define _GPX_NAME_TAIL          "</name>\n"
#define _GPX_DESC_HEAD          "<desc>"
#define _GPX_DESC_TAIL          "</desc>\n"
#define _GPX_SYM_HEAD           "<sym>"
#define _GPX_SYM_TAIL           "</sym>\n"
#define _GPX_ELE_HEAD           "<ele>"
#define _GPX_ELE_TAIL           "</ele>\n"
#define _GPX_SRC_HEAD           "<src>"
#define _GPX_SRC_TAIL           "</src>\n"
#define _GPX_TIME_HEAD          "<time>"
#define _GPX_TIME_TAIL          "</time>\n"


//Variables
static char _metaName[128];
static char _metaDesc[128];
static char _name[128];
static char _desc[128];
static char _ele[64];
static char _sym[64];
static char _src[64];
static char _time[128];


//Get methods

char *gpx_getOpen()
{
    return _GPX_HEAD;
}

char *gpx_getClose()
{
    return _GPX_TAIL;
}

void gpx_getMetaData(char *data)
{
    char localStr[1024] = {0};
    int offset = 0;

    sprintf(localStr, "%s", _GPX_META_HEAD);
    offset = strlen(_GPX_META_HEAD);

    if (strlen(_metaName) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_NAME_HEAD);
        offset += strlen(_GPX_NAME_HEAD);

        sprintf(localStr + offset, "<![CDATA[%s]]>", _metaName);
        offset += strlen("<![CDATA[]]>");
        offset += strlen(_metaName);

        sprintf(localStr + offset, "%s", _GPX_NAME_TAIL);
        offset += strlen(_GPX_NAME_TAIL);
    }

    if (strlen(_metaDesc) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_DESC_HEAD);
        offset += strlen(_GPX_DESC_HEAD);

        sprintf(localStr + offset, "<![CDATA[%s]]>", _metaDesc);
        offset += strlen("<![CDATA[]]>");
        offset += strlen(_metaDesc);

        sprintf(localStr + offset, "%s", _GPX_DESC_TAIL);
        offset += strlen(_GPX_DESC_TAIL);
    }

    sprintf(localStr + offset, "%s", _GPX_META_TAIL);

    if (RT_NULL != data) {
        sprintf(data, "%s", localStr);
    }

    return ;
}

char *gpx_getTrakOpen()
{
    return _GPX_TRAK_HEAD;
}

char *gpx_getTrakClose()
{
    return _GPX_TRAK_TAIL;
}

char *gpx_getTrakSegOpen()
{
    return _GPX_TRKSEG_HEAD;
}

char *gpx_getTrakSegClose()
{
    return _GPX_TRKSEG_TAIL;
}

void gpx_getInfo(char *info)
{
    char localStr[1024] = {0};
    int offset = 0;

    if (strlen(_name) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_NAME_HEAD);
        offset += strlen(_GPX_NAME_HEAD);

        sprintf(localStr + offset, "<![CDATA[%s]]>", _name);
        offset += strlen("<![CDATA[]]>");
        offset += strlen(_name);

        sprintf(localStr + offset, "%s", _GPX_NAME_TAIL);
        offset += strlen(_GPX_NAME_TAIL);
    }

    if (strlen(_desc) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_DESC_HEAD);
        offset += strlen(_GPX_DESC_HEAD);

        sprintf(localStr + offset, "<![CDATA[%s]]>", _desc);
        offset += strlen("<![CDATA[]]>");
        offset += strlen(_desc);

        sprintf(localStr + offset, "%s", _GPX_DESC_TAIL);
        offset += strlen(_GPX_DESC_TAIL);
    }

    if (RT_NULL != info) {
        sprintf(info, "%s", localStr);
    }

    return ;
}

void gpx_getPt(char *typ, char *lon, char *lat, char *pt)
{
    char localStr[1024] = {0};
    int offset = 0;

    sprintf(localStr, _GPX_PT_HEAD, typ);
    offset = strlen(localStr);

    sprintf(localStr + offset, "%s\" lon=\"%s\">", lat, lon);
    offset = strlen(localStr);

    if (strlen(_ele) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_ELE_HEAD);
        offset += strlen(_GPX_ELE_HEAD);

        sprintf(localStr + offset, "%s", _ele);
        offset += strlen(_ele);

        sprintf(localStr + offset, "%s", _GPX_ELE_TAIL);
        offset += strlen(_GPX_ELE_TAIL);
    }

    if (strlen(_time) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_TIME_HEAD);
        offset += strlen(_GPX_TIME_HEAD);

        sprintf(localStr + offset, "%s", _time);
        offset += strlen(_time);

        sprintf(localStr + offset, "%s", _GPX_TIME_TAIL);
        offset += strlen(_GPX_TIME_TAIL);
    }

    if (strlen(_sym) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_SYM_HEAD);
        offset += strlen(_GPX_SYM_HEAD);

        sprintf(localStr + offset, "%s", _sym);
        offset += strlen(_sym);

        sprintf(localStr + offset, "%s", _GPX_SYM_TAIL);
        offset += strlen(_GPX_SYM_TAIL);
    }

    if (strlen(_src) > 0)
    {
        sprintf(localStr + offset, "%s", _GPX_SRC_HEAD);
        offset += strlen(_GPX_SRC_HEAD);

        sprintf(localStr + offset, "%s", _src);
        offset += strlen(_src);

        sprintf(localStr + offset, "%s", _GPX_SRC_TAIL);
        offset += strlen(_GPX_SRC_TAIL);
    }

    sprintf(localStr + offset, _GPX_PT_TAIL, typ);

    if (RT_NULL != pt) {
        sprintf(pt, "%s", localStr);
    }

    return ;
}

//Set Methods
void gpx_setMetaName(char *name)
{
    memset(_metaName, 0x0, sizeof(name));
    sprintf(_metaName, "%s", name);
}

void gpx_setMetaDesc(char *desc)
{
    memset(_metaDesc, 0x0, sizeof(desc));
    sprintf(_metaDesc, "%s", desc);
}

void gpx_setName(char *name)
{
    memset(_name, 0x0, sizeof(name));
    sprintf(_name, "%s", name);
}

void gpx_setDesc(char *desc)
{
    memset(_desc, 0x0, sizeof(desc));
    sprintf(_desc, "%s", desc);
}

void gpx_setEle(char *ele)
{
    memset(_ele, 0x0, sizeof(ele));
    sprintf(_ele, "%s", ele);
}

void gpx_setSym(char *sym)
{
    memset(_sym, 0x0, sizeof(sym));
    sprintf(_sym, "%s", sym);
}

void gpx_setSrc(char *src)
{
    memset(_src, 0x0, sizeof(_src));
    sprintf(_src, "%s", src);
}

void gpx_setTime(char *time)
{
    memset(_time, 0x0, sizeof(time));
    sprintf(_time, "%s", time);
}
